/**
 * 
 */
package gamePlay;

import gui.LoaderGif;
import interfaces.Game;

import java.util.concurrent.TimeUnit;

import main.Session;
import main.SharedPref;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.wb.swt.SWTResourceManager;

import Utils.Concurrent.ThreadTasks.Timer;
import Utils.Concurrent.ThreadTasks.UpdateUserScoreTask;

import datatype.Question;
import datatype.Statistics;

/**
 * @author Yuval manage the gui of the game section in the application, the
 *         prepareQuestionScreen function create the game screen with the
 *         questions and the answers buttons
 */
public class Play {

	private Composite startGame, loadingNextLevel, loadingNextQuestions, stats,
			gameScreen, main;
	private Button startLevel, startLong, startTheGame, continueLevel,
			continueLoading, statsContinue;
	private Label theQuestion, gameInfo, nextLevelInfo, statsLBL, updateLBL;
	private Timer timer;
	private Canvas statsCanvas;
	private AbsGame theGame;

	private Composite game_answer_consol;
	private UpdateUserScoreTask updateUserScoreTask;
	private LoaderGif statsLG = null;;

	public Play(Composite startGame, Composite loadingNextLevel,
			Composite loadingNextQuestions, Composite stats,
			Composite gameScreen, Composite main, Button startLevel,
			Button startLong, Button startTheGame, Button continueLevel,
			Button continueLoading, Button statsContinue, Label theQuestion,
			Timer timer, Label gameInfo, Label nextLevelInfo, Label statsLBL,
			Label updateLBL, Canvas statsCanvas) {
		super();
		this.startGame = startGame;
		this.loadingNextLevel = loadingNextLevel;
		this.loadingNextQuestions = loadingNextQuestions;
		this.stats = stats;
		this.gameScreen = gameScreen;
		this.main = main;
		this.startLevel = startLevel;
		this.startLong = startLong;
		this.startTheGame = startTheGame;
		this.continueLevel = continueLevel;
		this.continueLoading = continueLoading;
		this.statsContinue = statsContinue;
		this.theQuestion = theQuestion;
		this.timer = timer;
		this.gameInfo = gameInfo;
		this.nextLevelInfo = nextLevelInfo;
		this.statsLBL = statsLBL;
		this.updateLBL = updateLBL;
		this.statsCanvas = statsCanvas;

		prepareWidgets();
	}

	private void changeScreenTo(Composite c) {
		Session.gui.changeScreenTo(c);
	}

	private void prepareWidgets() {

		startLevel.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent arg0) {
				startLevelGame();
			}

		});

		startLong.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent arg0) {
				startLongGame();
			}

		});

		startTheGame.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent arg0) {
				startGame();

			}
		});

		continueLoading.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseDown(MouseEvent arg0) {
				changeScreenTo(gameScreen);
				prepareQuestionScreen(((LongMod) theGame).resume());
			}
		});

		statsContinue.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseDown(MouseEvent arg0) {
				Session.game = null;
				theGame = null;
				changeScreenTo(main);

			}
		});
	}

	public void startLevelGame() {
		LevelMod levelMod = new LevelMod(SharedPref.levelModLengths.length);
		Session.game = (AbsGame) levelMod;
		theGame = levelMod;

		changeScreenTo(startGame);
		showStartGameScreen(true);

	}

	public void startLongGame() {
		LongMod longMod = new LongMod();
		Session.game = longMod;
		theGame = longMod;

		changeScreenTo(startGame);
		showStartGameScreen(false);

	}

	private void showStartGameScreen(boolean isLevelMod) {
		String str = "";
		if (isLevelMod)
			str = "You are about to start playing the level mod \r"
					+ "You have "
					+ ((LevelMod) theGame).getNumberOfLevels()
					+ " levels to finish the game\r"
					+ "each level has a growing number of questions \r"
					+ "And for each question you have "+SharedPref.timerTime+" seconds\r"
					+ "\r"
					+ "In case you choose the wrong answer\r"
					+ " you will lose the game and will have to start all over again";

		else
			str = "You are about to start playing in Long mod \r"
					+ "The game continues as long as you answer correctly\r"
					+ "Your goal is to create the longest chain of correct answers \r"
					+ "If you choose the wrong answer, you will lose\r"
					+ "Each question you have "+SharedPref.timerTime+" seconds to answer\r" + "\r"
					+ "Will YOU make the longest chain?";
		gameInfo.setText(str);

	}

	public void startGame() {
		// next button in the start game screen activate this function

		if (Session.game instanceof LongMod)
			((LongMod) Session.game).prapereChain();

		prepareQuestionScreen(Session.game.startGame());
		changeScreenTo(gameScreen);

		// timer activate or something...

	}

	private void prepareQuestionScreen(Question q) {

		// make the answer panel
		Session.pool.addKillerTaskToPool(true, timer);

		if (game_answer_consol != null)
			game_answer_consol.dispose();

		game_answer_consol = new Composite(gameScreen, SWT.BORDER);
		game_answer_consol.setBackground(SWTResourceManager
				.getColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
		game_answer_consol.setBounds(48, 254, 700, 420);
		game_answer_consol.layout(true);

		theQuestion.setText(q.getQuestion());

		int ans = 0;
		for (String answer : q.getAnswerList()) {
			Button b = new Button(game_answer_consol, SWT.BORDER);
			b.setBounds(100, 20 + 100 * ans, 500, 80);
			b.setText(answer);
			if (SharedPref.DEBUG && ans != q.getAnswer())
				b.setEnabled(false);
			prepareAnswerBTN(b, ans);
			gameScreen.redraw();
			gameScreen.update();
			ans++;
		}

	}

	private void prepareAnswerBTN(Button b, final int ans) {

		b.addMouseListener(new MouseAdapter() {

			@SuppressWarnings("unchecked")
			@Override
			public void mouseDown(MouseEvent arg0) {
				Game game = Session.game;
				boolean correct = game.chooseAnswer(ans);

				// kill the timer
				Session.pool.killAll(timer);

				if (!correct) {// if he failed to answer
					game.finishGame();

					showStatsScreen(false);
				} else {
					Question nextQues = game.nextQuestion();

					if (nextQues != null) {// we have more question
						prepareQuestionScreen(nextQues);
					} else {
						if (game instanceof LevelMod) {
							// he finished the level

							game.finishGame();

							if (((LevelMod) game).haveMoreLevels()) {
								// he didn't finish the game
								nextLevel(((LevelMod) game).getCurrentLevel().getLevel()); // we show the next level screen
							} else {// he finished the game
								// finishGame();
								showStatsScreen(true);
							}
						} else {
							if (((LongMod) game).isNextReady()) {
								prepareQuestionScreen(((LongMod) game).resume());
							} else {
								((LongMod) game).stop();
								loadingLongChainScreen();
							}
						}
					}
				}
			}
		});

	}

	public void showStatsScreen(boolean isWon) {

		if (statsLG == null)
			statsLG = new LoaderGif(statsCanvas, 1);

		updateLBL.setVisible(true);
		statsCanvas.setVisible(true);

		if (updateUserScoreTask != null)
			Session.poolTheQuestions.killAll(updateUserScoreTask,
					statsLG.getLoaderTask());

		Statistics s = theGame.getStats();
		s.setFinish(isWon);

		boolean isLevelMod = (theGame instanceof LevelMod);
		int bestScore = isLevelMod ? Session.user.getBestLevel() : Session.user
				.getBestLong();

		if (bestScore < s.getScore()) {
			statsContinue.setVisible(false);
			String mod = isLevelMod ? "Level" : "Long";
			updateUserScoreTask = new UpdateUserScoreTask(
					Session.gui.getDisplay(), statsLG, Session.user.getId(),
					mod, s.getScore(), statsContinue, updateLBL);
			Session.poolTheQuestions.pushUrgentTask(updateUserScoreTask,
					statsLG.getLoaderTask());
		}

		String str = "";

		if (isLevelMod) {
			if (isWon)
				str = "You Won the Game!! \r\r";
			else
				str = "You lose the Game!! \r\r";
			str += "Level passed: " + s.getLevel() + "\r"
					+ "Total Correct answers: " + s.getTotalCorrectAnswers();

		} else {
			((LongMod) theGame).killTask();
			str = "you made chain " + s.getTotalCorrectAnswers()
					+ " questins long";

		}

		str += "\r"
				+ "Total Score: "
				+ s.getScore()
				+ "\r"
				+ "Total Time played: "
				+ String.format(
						"%d min, %d sec",
						TimeUnit.MILLISECONDS.toMinutes(s.getTotlaTime()),
						TimeUnit.MILLISECONDS.toSeconds(s.getTotlaTime())
								- TimeUnit.MINUTES
										.toSeconds(TimeUnit.MILLISECONDS
												.toMinutes(s.getTotlaTime())));
		statsLBL.setText(str);
		changeScreenTo(stats);

	}

	public void nextLevel(int nextLevel) {
		changeScreenTo(loadingNextLevel);
		String str = "You have successfully finished the current level\rplease wait untill next level will be loaded\r"
				+ "\rprepare for " + SharedPref.levelModLengths[nextLevel] + " new questions!";
		// TODO add levels
		nextLevelInfo.setText(str);

		continueLevel.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseDown(MouseEvent arg0) {
				((LevelMod) Session.game).nextLevel();
				prepareQuestionScreen(Session.game.startGame());
				changeScreenTo(gameScreen);

			}

		});

	}

	public void loadingLongChainScreen() {

		changeScreenTo(loadingNextQuestions);

	}

}
